﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Aribaccio;
using BDPAutodetect.Device;
using CommunityToolkit.Mvvm.ComponentModel;

namespace BDPAutodetect.Models
{
    /// <summary>
    /// 工位传输数据
    /// </summary>
    public partial class MStationDetectDto : ObservableModel
    {
        /// <summary>
        /// 工位信息
        /// </summary>
        [ObservableProperty]
        protected MStation station;

        /// <summary>
        /// 检测状态
        /// </summary>
        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(IsEnabledStart))]
        [NotifyPropertyChangedFor(nameof(IsEnabledStop))]
        [NotifyPropertyChangedFor(nameof(IsEnabledPause))]
        [NotifyPropertyChangedFor(nameof(IsEnabledContinue))]
        protected DetectJobStatus detectStatus;

        /// <summary>
        /// 检测信息
        /// </summary>
        [ObservableProperty]
        protected string? detectMsg;

        /// <summary>
        /// 条码
        /// </summary>
        [ObservableProperty]
        protected string? barcode;

        /// <summary>
        /// 扫码枪启用禁止状态
        /// </summary>
        [ObservableProperty]
        public bool barcodeEnable;

        /// <summary>
        /// 启动时间
        /// </summary>
        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(DetectTimeDiff))]
        [NotifyPropertyChangedFor(nameof(DetectTimeDiffDisplay))]
        protected DateTime startDateTime;

        /// <summary>
        /// 结束时间
        /// </summary>
        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(DetectTimeDiff))]
        [NotifyPropertyChangedFor(nameof(DetectTimeDiffDisplay))]
        protected DateTime finishDateTime;

        /// <summary>
        /// 信号灯颜色
        /// </summary>
        [ObservableProperty]
        protected Color signalColor;

        /// <summary>
        /// 电机机电数据
        /// </summary>
        [ObservableProperty]
        protected MStationMotor motorData;

        /// <summary>
        /// 参数配置数据
        /// </summary>
        [ObservableProperty]
        protected MParameterData? parameterData;

        /// <summary>
        /// 检测统计数据
        /// </summary>
        [ObservableProperty]
        protected MStationDetectTotal totalData;

        /// <summary>
        /// 扫码枪是否启用状态-参数实例
        /// </summary>
        [ObservableProperty]
        protected MSettingSystem? settingEnableBarcode;

        /// <summary>
        /// 检测指标数据集
        /// </summary>
        [ObservableProperty]
        protected ObservableCollection<MTargetDetectDto> targetDatas;

        /// <summary>
        /// 工位类型
        /// </summary>
        public DeviceStationType StationType => this.Station?.StationType ?? DeviceStationType.None;

        /// <summary>
        /// 检测执行时间(单位/s)
        /// </summary>
        public int DetectTimeDiff { get => this.ConvertDateTimeDiff(this.StartDateTime, this.FinishDateTime); }

        /// <summary>
        /// 检测执行显示时间
        /// </summary>
        public string DetectTimeDiffDisplay { get => this.ConvertDateTimeDiffDisplay(this.StartDateTime, this.FinishDateTime); }

        /// <summary>
        /// 是否可见继续按钮
        /// </summary>
        public bool IsEnabledContinue => this.DetectStatus == DetectJobStatus.Pause;

        /// <summary>
        /// 是否可见启动按钮
        /// </summary>
        public bool IsEnabledStart => this.DetectStatus == DetectJobStatus.None || this.DetectStatus == DetectJobStatus.Finish;

        /// <summary>
        /// 是否可见停止按钮
        /// </summary>
        public bool IsEnabledStop => this.DetectStatus != DetectJobStatus.None && this.DetectStatus != DetectJobStatus.Finish;

        /// <summary>
        /// 是否可见暂停按钮
        /// </summary>
        public bool IsEnabledPause => this.DetectStatus != DetectJobStatus.Pause && this.DetectStatus != DetectJobStatus.None && this.DetectStatus != DetectJobStatus.Finish;

        /// <summary>
        /// 是否所有检测结束
        /// </summary>
        public bool IsDetectFinish => !this.TargetDatas.ToList().Exists(v => v != null && v.DetectStatus != DetectJobStatus.Finish);
        /// <summary>
        /// 是否合格 所有检测结果
        /// </summary>
        public bool IsDetectResultPass => !this.TargetDatas.ToList().Exists(v => v != null && v.DetectResultPassStatus != DetectResultStatus.Pass);
        /// <summary>
        /// 检测结果是否合格
        /// </summary>
        public DetectResultStatus DetectResultStatus => IsDetectFinish ? (this.IsDetectResultPass ? DetectResultStatus.Pass : DetectResultStatus.Fail) : DetectResultStatus.None;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="argStation">工位</param>
        public MStationDetectDto(MStation argStation)
        {
            this.BarcodeEnable = true;
            this.Station = argStation;
            this.StartDateTime = default;
            this.FinishDateTime = default;
            this.SignalColor = Color.Gray;
            this.DetectStatus = DetectJobStatus.None;
            this.MotorData = new MStationMotor();
            this.TotalData = new MStationDetectTotal() { Station = argStation };
            this.TargetDatas = new ObservableCollection<MTargetDetectDto>();
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="argStation">工位</param>
        /// <param name="argTotalData">统计数据</param>
        /// <param name="argStationTargets">指标明显数据集</param>
        /// <param name="argSettingEnableBarcode">扫码枪启用设置</param>
        public MStationDetectDto(MStation argStation, MStationDetectTotal? argTotalData, List<MTargetDetectDto> argStationTargets, MSettingSystem? argSettingEnableBarcode)
            : this(argStation)
        {
            this.TargetDatas = new ObservableCollection<MTargetDetectDto>(argStationTargets);
            if (argTotalData != null) this.TotalData = argTotalData;
            this.SettingEnableBarcode = argSettingEnableBarcode;
            this.BarcodeEnable = argSettingEnableBarcode?.GetData(true) ?? true;
            if (this.SettingEnableBarcode != null)
            {
                this.SettingEnableBarcode.DatumChangedAction += OnChangedEnableBarcodeDatum;
            }           
        }

        /// <summary>
        /// 重置清理数据
        /// </summary>
        public void Reset()
        {
            this.StartDateTime = default;
            this.FinishDateTime = default;
            this.Barcode = string.Empty;
            this.DetectMsg = string.Empty;
            this.DetectStatus = DetectJobStatus.None;
            this.SignalColor = Color.Gray;
            this.MotorData.Reset();
            foreach (var item in this.TargetDatas)
            {
                item.Reset();
            }
        }

        /// <summary>
        /// 设置检测指标参数界限范围
        /// </summary>
        public void SetTargetParameterLimit()
        {
            if (this.ParameterData == null || this.ParameterData.Limits == null || this.ParameterData.Limits.Count <= 0) return;
            foreach (var targetData in this.TargetDatas)
            {
                targetData.ParameterLimit = null;
                if (targetData.TargetType == DeviceTargetType.None) continue;

                var limitData = this.ParameterData.Limits.FirstOrDefault(v => v.TargetType == targetData.TargetType);
                if (limitData == null) continue;

                targetData.ParameterLimit = limitData;
            }
        }

        /// <summary>
        /// 更新统计数据
        /// </summary>
        public void IncreaseTotalData(int argAdditionValue = 1)
        {
            this.TotalData.DetectCount += argAdditionValue;
            this.TotalData.DetectDuration += this.DetectTimeDiff;
        }

        /// <summary>
        /// 深度克隆
        /// </summary>
        public MStationDetectDto CloneDeep()
        {
            var result = new MStationDetectDto(this.Station.CloneDeep())
            {
                StartDateTime = this.StartDateTime,
                FinishDateTime = this.FinishDateTime,
                DetectStatus = this.DetectStatus,
                DetectMsg = this.DetectMsg,
                Barcode = this.Barcode,
                SettingEnableBarcode = this.SettingEnableBarcode,
                SignalColor = this.SignalColor,
                MotorData = this.MotorData.CloneDeep(),
                TotalData = this.TotalData.CloneDeep(),
                ParameterData = this.ParameterData?.CloneDeep()
            };
            foreach (var item in this.TargetDatas)
            {
                result.TargetDatas.Add(item.CloneDeep());
            }
            return result;
        }

        /// <summary>
        /// 深度克隆统计数据
        /// </summary>
        /// <returns></returns>
        public MStationDetectTotal CloneDeepTotal()
        {
            return this.TotalData.CloneDeep();
        }

        /// <summary>
        /// 计算检测执行时间(单位/s)
        /// </summary>
        /// <param name="argDateBegin">开始时间</param>
        /// <param name="argDateEnd">结束时间</param>
        /// <returns>返回(xx分xx秒)单位字符串</returns>
        protected int ConvertDateTimeDiff(DateTime argDateBegin, DateTime argDateEnd)
        {
            if (argDateBegin == default(DateTime) || argDateEnd == default(DateTime) || DateTime.Compare(argDateBegin, argDateEnd) >= 0) { return 0; }
            try
            {
                TimeSpan ts1 = new TimeSpan(argDateBegin.Ticks);
                TimeSpan ts2 = new TimeSpan(argDateEnd.Ticks);
                TimeSpan ts3 = ts1.Subtract(ts2).Duration();
                return (int)ts3.TotalSeconds;
            }
            catch (Exception)
            {
                return 0;
            }
        }

        /// <summary>
        /// 计算检测执行时间(显示字符串)
        /// </summary>
        /// <param name="argDateBegin">开始时间</param>
        /// <param name="argDateEnd">结束时间</param>
        /// <returns>返回(xx分xx秒)单位字符串</returns>
        protected string ConvertDateTimeDiffDisplay(DateTime argDateBegin, DateTime argDateEnd)
        {
            if (argDateBegin == default(DateTime) || argDateEnd == default(DateTime) || DateTime.Compare(argDateBegin, argDateEnd) >= 0) { return "00分00秒"; }
            try
            {
                TimeSpan ts1 = new TimeSpan(argDateBegin.Ticks);
                TimeSpan ts2 = new TimeSpan(argDateEnd.Ticks);
                TimeSpan ts3 = ts1.Subtract(ts2).Duration();
                int MinutesDays = ts3.Days * 24 * 60;
                int MinutesHours = ts3.Hours * 60;
                //你想转的格式
                return $"{(MinutesDays + MinutesHours + ts3.Minutes)}分{ts3.Seconds}秒";
            }
            catch (Exception)
            {
                return "00分00秒";
            }
        }

        /// <summary>
        /// 扫码枪启用设置改变事件
        /// </summary>
        protected void OnChangedEnableBarcodeDatum()
        {
            this.BarcodeEnable = this.SettingEnableBarcode?.GetData(true) ?? true;
        }
    }
}
